﻿/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../global/head.h"
#include "config.h"

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace xos_log
{

    config::config( i_log * pLog )
    {
        m_pLog = pLog;
    }

    config::~config()
    {
    }

    ////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int config::load_config_file( const char * lpszConfigFile )
    {
        int ret = 0;

        xos_xml::i_xml_doc * pXmlDoc = 0;
        xos_xml::i_xml_node * pRoot = 0;

        if( 0 == ret )
        {
            ret = g_pSysData->m_pXmlMgr->create_doc( &pXmlDoc );
        }

        if( 0 == ret )
        {
            ret = pXmlDoc->load_xml_file( lpszConfigFile );
        }

        if( 0 == ret )
        {
            ret = pXmlDoc->get_root_node( &pRoot );
        }

        if( 0 == ret )
        {
            ret = load_config_info( pRoot );
        }

        if( pRoot )
        {
            pRoot->release();
            pRoot = 0;
        }

        if( pXmlDoc )
        {
            pXmlDoc->release();
            pXmlDoc = 0;
        }

        return ret;
    }

    int config::load_config_string( const char * lpszConfigString )
    {
        int ret = 0;

        xos_xml::i_xml_doc * pXmlDoc = 0;
        xos_xml::i_xml_node * pRoot = 0;

        if( 0 == ret )
        {
            ret = g_pSysData->m_pXmlMgr->create_doc( &pXmlDoc );
        }

        if( 0 == ret )
        {
            ret = pXmlDoc->load_xml_string( lpszConfigString );
        }

        if( 0 == ret )
        {
            ret = pXmlDoc->get_root_node( &pRoot );
        }

        if( 0 == ret )
        {
            ret = load_config_info( pRoot );
        }

        if( pRoot )
        {
            pRoot->release();
            pRoot = 0;
        }

        if( pXmlDoc )
        {
            pXmlDoc->release();
            pXmlDoc = 0;
        }

        return ret;
    }

    ///////////////////////////////////////////////////////////////////////////////////////////
    // 帮助函数

    int config::load_config_info( xos_xml::i_xml_node * pRoot )
    {
        int ret = 0;

        xos_xml::i_xml_node * pChild = 0;
        xos_xml::i_xml_node * pT = 0;

        if( 0 == ret )
        {
            ret = pRoot->get_child_node( &pChild );
        }

        while( ( 0 == ret ) && pChild )
        {
            char name[1024] = { 0 };
            pChild->get_node_name( name, sizeof( name ), 0 );
            if( 0 == g_pSysData->m_pContainer->crt()->stricmp( name, "logs" ) )
            {
                load_log_modules( pChild );
                pChild->release();
                pChild = 0;
                break;
            }
            pT = pChild;
            pChild = 0;
            pT->get_next_sibling_node( &pChild );
            pT->release();
            pT = 0;
        }

        return ret;
    }

    int config::load_log_modules( xos_xml::i_xml_node * pLogs )
    {
        int ret = 0;

        xos_xml::i_xml_node * pLog = 0;
        xos_xml::i_xml_node * pT = 0;

        if( 0 == ret )
        {
            ret = pLogs->get_child_node( &pLog );
        }

        while( ( 0 == ret ) && pLog )
        {
            load_log_module( pLog );
            pT = pLog;
            pLog = 0;
            pT->get_next_sibling_node( &pLog );
            pT->release();
            pT = 0;
        }

        return ret;
    }

    int config::load_log_module( xos_xml::i_xml_node * pLog )
    {
        int ret = 0;

        xos_xml::i_xml_node * pEnable = 0;
        xos_xml::i_xml_node * pLevels = 0;
        xos_xml::i_xml_node * pName = 0;

        xos_xml::i_xml_node * pChild = 0;
        xos_xml::i_xml_node * pT = 0;

        char szName[1024] = { 0 };
        int nEnable = 0;

        if( 0 == ret )
        {
            ret = pLog->get_child_node( &pChild );
        }

        while( ( 0 == ret ) && pChild )
        {
            char name[1024] = { 0 };
            pChild->get_node_name( name, sizeof( name ), 0 );
            if( 0 == g_pSysData->m_pContainer->crt()->stricmp( name, "levels" ) )
            {
                pChild->clone( &pLevels );
            }
            else if( 0 == g_pSysData->m_pContainer->crt()->stricmp( name, "name" ) )
            {
                pChild->clone( &pName );
            }
            else if( 0 == g_pSysData->m_pContainer->crt()->stricmp( name, "enable" ) )
            {
                pChild->clone( &pEnable );
            }
            pT = pChild;
            pChild = 0;
            pT->get_next_sibling_node( &pChild );
            pT->release();
            pT = 0;
        }

        if( ( 0 == ret ) && ( !pEnable || !pLevels || !pName ) )
        {
            ret = 1;
        }

        if( 0 == ret )
        {
            char v[1024] = { 0 };
            ret = pEnable->get_node_value( v, sizeof( v ), 0 );
            if( 0 == ret )
            {
                nEnable = g_pSysData->m_pContainer->crt()->atoi( v );
                if( 0 == nEnable )
                {
                    ret = 1;
                }
            }
        }

        if( 0 == ret )
        {
            ret = pName->get_node_value( szName, sizeof( szName ), 0 );
        }

        if( 0 == ret )
        {
            ret = load_log_levels( szName, pLevels );
        }

        if( pEnable )
        {
            pEnable->release();
            pEnable = 0;
        }

        if( pLevels )
        {
            pLevels->release();
            pLevels = 0;
        }

        if( pName )
        {
            pName->release();
            pName = 0;
        }

        return ret;
    }

    int config::load_log_levels( const char * lpszModuleName, xos_xml::i_xml_node * pLevels )
    {
        int ret = 0;

        xos_xml::i_xml_node * pLevel = 0;
        xos_xml::i_xml_node * pT = 0;

        if( 0 == ret )
        {
            ret = pLevels->get_child_node( &pLevel );
        }

        while( ( 0 == ret ) && pLevel )
        {
            load_log_level( lpszModuleName, pLevel );
            pT = pLevel;
            pLevel = 0;
            pT->get_next_sibling_node( &pLevel );
            pT->release();
            pT = 0;
        }

        return ret;
    }

    int config::load_log_level( const char * lpszModuleName, xos_xml::i_xml_node * pLevel )
    {
        int ret = 0;

        char v[1024] = { 0 };

        if( 0 == ret )
        {
            ret = pLevel->get_node_value( v, sizeof( v ), 0 );
        }

        if( 0 == ret )
        {
            int nLevel = g_pSysData->m_pContainer->crt()->atoi( v );
            ret = m_pLog->add_log_module( lpszModuleName, nLevel );
        }

        return ret;
    }

} // xos_log
